#!/bin/bash

# Elasticsearch管理脚本
# 需要提前安装curl

ES_HOST="localhost"
ES_PORT="9200"
ES_USER="elastic"
ES_PASS=""
INDEX_NAME=""
SHARDS=3
REPLICAS=1

usage() {
    echo "使用方法: $0 [选项]"
    echo "选项:"
    echo "  -h, --host       Elasticsearch主机(默认: localhost)"
    echo "  -p, --port       端口(默认: 9200)"
    echo "  -u, --user       用户名(默认: elastic)"
    echo "  -P, --password   密码(默认: 不填写代表无密码)"
    echo "  -i, --index      索引名称"
    echo "  -s, --shards     分片数(默认: 3)"
    echo "  -r, --replicas   副本数(默认: 1)"
    echo "  -q, --query      查询条件(JSON文件路径)"
    echo "  -a, --action     指定操作类型
                                get_cls    ： 获取集群信息
                                list_index ： 列出所有索引
                                get_index  ： 获取索引信息
                                get_stats  ： 获取索引状态
                                ops_data   ： 操作索引数据(统计、查询、删除)
                                add_index  ： 添加索引
                                del_index  ： 删除索引
        "
    exit 1
}

check_command() {
    if ! command -v $1 &> /dev/null; then
        echo "错误：未找到 $1 命令，请安装后再运行"
        exit 1
    fi
}

check_command curl

# 基础curl命令构造
base_curl() {
    local url=$1
    local method=${2:-GET}
    local data=${3:-""}
    
    auth=""
    if [ -n "$ES_USER" ] && [ -n "$ES_PASS" ]; then
        auth="-u $ES_USER:$ES_PASS"
    fi

    if [ -z "$data" ]; then
        response=$(curl -s -X $method $auth "$ES_HOST:$ES_PORT/$url")
    else
        response=$(curl -s -X $method $auth -H "Content-Type: application/json" "$ES_HOST:$ES_PORT/$url" -d "$data")
    fi

    # if echo "$response" | jq -e '.error' >/dev/null; then
    #     echo "错误: $(echo $response | jq -r '.error.reason')"
    #     exit 1
    # fi
    
    echo "$response"
}


# 集群健康状态
get_cls() {
    echo "集群健康状态:"
    base_curl "_cluster/health?pretty"
    echo "----------------------分割线----------------------"
    echo "节点信息:"
    base_curl "_cat/nodes?v&pretty" | awk 'NR==1 {print} NR>1 {print $0}' | column -t
}

# 列出所有索引
list_index() {
    echo "索引列表:"
    base_curl "_cat/indices?v&pretty" | column -t
}

# 查看索引信息
get_index() {
    if [ -z "$INDEX_NAME" ]; then
        echo "错误: 必须指定索引名称【-i】"
        exit 1
    fi
    echo "-------------{$INDEX_NAME}索引别名:"
    base_curl "$INDEX_NAME/_alias?pretty"

    echo "-------------{$INDEX_NAME}索引映射:"
    base_curl "$INDEX_NAME/_mapping?pretty"

    echo "-------------{$INDEX_NAME}索引设置:"
    base_curl "$INDEX_NAME/_setting?pretty"
}

# 索引统计信息
get_stats() {
    if [ -z "$INDEX_NAME" ]; then
        echo "错误: 必须指定索引名称【-i】"
        exit 1
    fi
    echo "{$INDEX_NAME}索引统计信息:"
    base_curl "$INDEX_NAME/_stats?pretty"
}

# 查询索引数据
ops_data() {
    if [ -z "$INDEX_NAME" ] || [ -z "$QUERY" ] || [ -z "$OPTION" ]; then
        echo "错误: 必须指定索引名称【-i】和查询文件【-q】和作用【-o】"
        echo '
查询文件【-q】示例：cat /root/a.json
{
  "query": {
   "bool": {
     "must": [
        { "term": { "alarmName.keyword": "CPU使用率连续3次大于等于85%" } },
        { "term": {"instanceName.keyword": "Linux_10.100.111.75"}},
        {
          "nested": {
            "path": "businessSystem",
            "query": {
              "term": {
                "businessSystem.cmdbId": "information_system_1750724085673615360"
              }
            }
          }
        }
     ]
   }
  }
}

作用【-o】选项：
    n： 统计数据量
    s： 查询索引数据
    d： 删除索引数据

执行查询：
    sh ex.sh -h 10.2.158.42 -a index_data -i alarms_202504 -q /root/a.json -o s > /root/a.txt
执行删除：
    sh ex.sh -h 10.2.158.42 -a index_data -i alarms_202504 -q /root/a.json -o d
'
        exit 1
    fi
    if [ ! -f "$QUERY" ]; then
        echo "错误: 查询文件不存在"
        exit 1
    fi

    case "$OPTION" in
    "n")
        data=$(cat $QUERY)
        result=$(base_curl "$INDEX_NAME/_count?pretty" "GET" "$data")
        echo "{$INDEX_NAME}索引数据查询结果:"
        echo "$result"
        ;;
    "s")
        data=$(cat $QUERY)
        result=$(base_curl "$INDEX_NAME/_search?pretty" "POST" "$data")
        echo "{$INDEX_NAME}索引数据查询结果:"
        echo "$result"
        ;;
    "d")
        data=$(cat $QUERY)
        result=$(base_curl "$INDEX_NAME/_delete_by_query?pretty" "POST" "$data")
        echo "{$INDEX_NAME}索引数据删除结果:"
        echo "$result"
        ;;
    *)
        echo "错误: 作用选项使用错误"
        exit 1
        ;;
    esac

}

# 创建索引
add_index() {
    if [ -z "$INDEX_NAME" ]; then
        echo "错误: 必须指定索引名称"
        exit 1
    fi

    data=$(cat <<EOF
{
    "settings": {
        "index": {
            "number_of_shards": $SHARDS,
            "number_of_replicas": $REPLICAS
        }
    }
}
EOF
    )
    
    result=$(base_curl "$INDEX_NAME" "PUT" "$data")
    echo "创建索引结果:"
    echo $result
}

# 删除索引
del_index() {
    if [ -z "$INDEX_NAME" ]; then
        echo "错误: 必须指定索引名称"
        exit 1
    fi

    read -p "确认要删除索引 $INDEX_NAME 吗？(y/n): " confirm
    if [ "$confirm" != "y" ]; then
        echo "取消删除操作"
        exit 0
    fi

    result=$(base_curl "$INDEX_NAME" "DELETE")
    echo "删除结果:"
    echo $result
}


# 参数解析
while [[ $# -gt 0 ]]; do
    case "$1" in
        -h|--host)
            ES_HOST="$2"
            shift 2
            ;;
        -p|--port)
            ES_PORT="$2"
            shift 2
            ;;
        -u|--user)
            ES_USER="$2"
            shift 2
            ;;
        -P|--password)
            ES_PASS="$2"
            shift 2
            ;;
        -a|--action)
            ACTION="$2"
            shift 2
            ;;
        -i|--index)
            INDEX_NAME="$2"
            shift 2
            ;;
        -s|--shards)
            SHARDS="$2"
            shift 2
            ;;
        -r|--replicas)
            REPLICAS="$2"
            shift 2
            ;;
        -q|--query)
            QUERY="$2"
            shift 2
            ;;
        -o|--option)
            OPTION="$2"
            shift 2
            ;;
        *)
            usage
            ;;
    esac
done

# 执行对应操作
case "$ACTION" in
    "get_cls")
        get_cls
        ;;
    "list_index")
        list_index
        ;;
    "get_index")
        get_index
        ;;
    "get_stats")
        get_stats
        ;;
    "ops_data")
        ops_data
        ;;
    "add_index")
        add_index
        ;;
    "del_index")
        del_index
        ;;
    *)
        echo "未知操作: $ACTION"
        usage
        ;;
esac